package com.srtp.secureprotocol.keychain.cipherStorage;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.srtp.secureprotocol.keychain.SecurityLevel;
import com.srtp.secureprotocol.keychain.exceptions.CryptoFailedException;
import com.srtp.secureprotocol.keychain.exceptions.KeyStoreAccessException;
import java.security.Key;

/**
 * 密码存储接口
 * 定义密钥管理和凭证加密/解密的核心操作
 * 支持不同安全级别的存储实现
 */
@SuppressWarnings({"unused", "WeakerAccess"})
public interface CipherStorage {

  //region 辅助类定义

  /**
   * 凭证存储基类（泛型）
   * 用于存储不同格式的用户名和密码
   */
  abstract class CipherResult<T> {
    public final T username;  // 用户名凭证
    public final T password;  // 密码凭证

    public CipherResult(final T username, final T password) {
      this.username = username;
      this.password = password;
    }
  }

  /**
   * 加密结果类
   * 存储字节数组格式的加密凭证
   */
  class EncryptionResult extends CipherResult<byte[]> {
    /** 使用的加密存储名称 */
    public final String cipherName;

    /** 主构造函数 */
    public EncryptionResult(final byte[] username, final byte[] password, final String cipherName) {
      super(username, password);
      this.cipherName = cipherName;
    }

    /** 辅助构造函数（自动提取存储名称） */
    public EncryptionResult(final byte[] username, final byte[] password, @NonNull final CipherStorage cipherStorage) {
      this(username, password, cipherStorage.getCipherStorageName());
    }
  }

  /**
   * 解密结果类
   * 存储字符串格式的解密凭证
   */
  class DecryptionResult extends CipherResult<String> {
    private final SecurityLevel securityLevel;  // 解密使用的安全级别

    public DecryptionResult(final String username, final String password) {
      this(username, password, SecurityLevel.ANY);
    }

    public DecryptionResult(final String username, final String password, final SecurityLevel level) {
      super(username, password);
      securityLevel = level;
    }

    /** 获取解密使用的安全级别 */
    public SecurityLevel getSecurityLevel() {
      return securityLevel;
    }
  }

  /**
   * 解密上下文类
   * 用于请求解密凭证所需的访问权限
   */
  class DecryptionContext extends CipherResult<byte[]> {
    public final Key key;        // 解密密钥
    public final String keyAlias; // 密钥别名

    public DecryptionContext(@NonNull final String keyAlias,
                             @NonNull final Key key,
                             @NonNull final byte[] password,
                             @NonNull final byte[] username) {
      super(username, password);
      this.keyAlias = keyAlias;
      this.key = key;
    }
  }

  /**
   * 带结果接口
   * 提供访问解密结果的属性和方法
   */
  interface WithResults {
    /** 获取解密结果 */
    @Nullable
    DecryptionResult getResult();

    /** 获取解密过程中的错误 */
    @Nullable
    Throwable getError();

    /** 阻塞线程等待解密结果 */
    void waitResult();
  }

  /**
   * 解密结果处理器接口
   * 处理解密过程中的交互和结果回调
   */
  interface DecryptionResultHandler extends WithResults {
    /**
     * 请求用户访问权限（如生物识别解锁）
     * @param context 解密上下文
     */
    void askAccessPermissions(@NonNull final DecryptionContext context);

    /**
     * 解密完成回调
     * @param decryptionResult 解密结果（成功时为非null）
     * @param error 错误信息（失败时为非null）
     */
    void onDecrypt(@Nullable final DecryptionResult decryptionResult, @Nullable final Throwable error);
  }
  //endregion

  //region 核心API方法

  /**
   * 加密凭证
   * @param alias 密钥别名
   * @param username 用户名
   * @param password 密码
   * @param level 要求的安全级别
   * @return 加密结果
   * @throws CryptoFailedException 加密失败时抛出
   */
  @NonNull
  EncryptionResult encrypt(@NonNull final String alias,
                           @NonNull final String username,
                           @NonNull final String password,
                           @NonNull final SecurityLevel level)
          throws CryptoFailedException;

  /**
   * 解密凭证
   * @param alias 密钥别名
   * @param username 加密的用户名（字节数组）
   * @param password 加密的密码（字节数组）
   * @param level 要求的安全级别
   * @return 解密结果
   * @throws CryptoFailedException 如果密钥存储的安全级别低于要求级别时抛出
   */
  @NonNull
  DecryptionResult decrypt(@NonNull final String alias,
                           @NonNull final byte[] username,
                           @NonNull final byte[] password,
                           @NonNull final SecurityLevel level)
          throws CryptoFailedException;

  /**
   * 解密凭证（结果通过处理器回调）
   * @param handler 解密结果处理器
   * @param alias 密钥别名
   * @param username 加密的用户名（字节数组）
   * @param password 加密的密码（字节数组）
   * @param level 要求的安全级别
   * @throws CryptoFailedException 解密失败时抛出
   */
  void decrypt(@NonNull final DecryptionResultHandler handler,
               @NonNull final String alias,
               @NonNull final byte[] username,
               @NonNull final byte[] password,
               @NonNull final SecurityLevel level)
          throws CryptoFailedException;

  /**
   * 移除密钥
   * @param alias 要移除的密钥别名
   * @throws KeyStoreAccessException 密钥库访问失败时抛出
   */
  void removeKey(@NonNull final String alias) throws KeyStoreAccessException;
  //endregion

  //region 配置信息

  /** 获取存储名称 */
  String getCipherStorageName();

  /** 获取支持的最低API级别 */
  int getMinSupportedApiLevel();

  /** 获取存储提供的安全级别 */
  SecurityLevel securityLevel();

  /** 是否支持安全硬件（TEE/SE） */
  boolean supportsSecureHardware();

  /** 是否支持生物识别 */
  boolean isBiometrySupported();

  /**
   * 获取能力级别（用于选择最佳存储）
   * 计算公式：
   * = 1000 * isBiometrySupported() +
   *   100 * isSecureHardware() +
   *   minSupportedApiLevel()
   */
  int getCapabilityLevel();

  /** 获取默认的服务别名 */
  String getDefaultAliasServiceName();
  //endregion
}